from crypt import methods
from flask_login import login_required
from flask import Blueprint, render_template, request, redirect
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, DateField, SelectField, IntegerField, FloatField, HiddenField
from sqlalchemy import and_
from .main import supplier
from ..models.models import Dbconn, Goods, Supplier, Purchase
import uuid
from sqlalchemy import or_, func
from datetime import datetime

pbp = Blueprint('purchase', __name__)


class PurchaseQuery(FlaskForm):
    db = Dbconn()
    goods = db.cursor.query(Goods).filter().all()
    goods_list = list()
    goods_list.append((-1, '请选择'))
    for good in goods:
        good_info = (good.id, f'{good.gname}-{good.brand}-{good.model}')
        goods_list.append(good_info)
    sups = db.cursor.query(Supplier).filter().all()
    sups_list = list()
    sups_list.append((-1, '请选择'))
    for sup in sups:
        sup_info = (sup.id, sup.name)
        sups_list.append(sup_info)
    sdate = DateField('开始日期')
    edate = DateField('结止日期')
    pgoods = SelectField('商品', choices=goods_list)
    psupplier = SelectField('供应商', choices=sups_list)
    pok = SubmitField('查询')


class PurchaseAddOrderForm(FlaskForm):
    db = Dbconn()
    goods = db.cursor.query(Goods).filter().all()
    goods_list = list()
    goods_list.append((-1, '请选择'))
    for good in goods:
        good_info = (good.id, f'{good.gname}-{good.brand}-{good.model}')
        goods_list.append(good_info)
    sups = db.cursor.query(Supplier).filter().all()
    sups_list = list()
    sups_list.append((-1, '请选择'))
    for sup in sups:
        sup_info = (sup.id, sup.name)
        sups_list.append(sup_info)
    pid = HiddenField('pid')
    code = StringField('编码', default=uuid.uuid1(), render_kw={'readonly':True})
    date = DateField('日期')
    goods = SelectField('商品', choices=goods_list)
    quantity = IntegerField('数量')
    univalence = FloatField('单价')
    supplier = SelectField('供应商', choices=sups_list)
    pok = SubmitField('保存')
    # pcancel = SubmitField('取消')


def get_purchase_orders(page=1, limit=10, **kwargs):
    if page <= 0:
        page = 1
    if limit <= 0:
        limit = 10
    _conditions = list()
    _conditions.append(Purchase.deleted==False)
    _snum = (page - 1) * limit + 1
    _pgoods = kwargs.get('pgoods')
    _psupllier = kwargs.get('psupllier')
    if _pgoods == -1:
        _pgoods = None
    if _psupllier == -1:
        _psupllier = None
    _sdate = kwargs.get('sdate')
    _edate = kwargs.get('edate')
    if _sdate:
        _sdate = datetime.strptime(_sdate, '%Y-%m-%d')
    else:
        _sdate = datetime.strptime('1900-1-1', '%Y-%m-%d')
    if _edate:
        _edate = datetime.strptime(_edate, '%Y-%m-%d')
    else:
        _edate = datetime.now()
    if  _psupllier:
        _conditions.append(Purchase.supplier==_psupllier)
    if  _pgoods:
        _conditions.append(Purchase.pgoods==_pgoods)
    _orders_list = list()
    _offset_num = (page - 1) * 10
    db = Dbconn()
    _orders_all = db.cursor.query(Purchase, Goods, Supplier).join(Goods, Purchase.pgoods == Goods.id). \
        join(Supplier, Purchase.supplier == Supplier.id). \
        filter(and_(*_conditions),
               Purchase.pdate.between(_sdate, _edate)
               ).all()
    _orders = db.cursor.query(Purchase, Goods, Supplier).join(Goods, Purchase.pgoods == Goods.id). \
        join(Supplier, Purchase.supplier == Supplier.id).\
        filter(and_(*_conditions),
                Purchase.pdate.between(_sdate, _edate)
               ). \
        order_by(Purchase.pdate.desc()).limit(limit). \
        offset(_offset_num).all()
    _cunt = len(_orders_all)
    for item in _orders:
        info = ['#',
                _snum,
                item.Purchase.pcode,
                item.Purchase.pdate,
                item.Goods.gname,
                item.Goods.brand,
                item.Goods.model,
                item.Purchase.univalence,
                item.Purchase.quantity,
                item.Goods.measure,
                item.Purchase.univalence * item.Purchase.quantity,
                item.Supplier.name,
                item.Purchase.id
                ]
        _snum = _snum + 1
        _orders_list.append(info)
    return {'content':_orders_list, 'count':_cunt}


@pbp.route('/purchase', methods=['GET', 'POST'])
@login_required
def purchase():
    pform = PurchaseQuery()
    page_limit = 10
    if not request.args.get('page'):
        page = 1
    else:
        page = int(request.args.get('page'))
    if page <= 0:
        page = 1
    tab = get_purchase_orders(page=page, limit=page_limit)
    # tab = get_purchase_orders(page=page, limit=page_limit, pgoods=3, psupllier=3)
    cunt = tab.get('count')
    if cunt % page_limit:
        max_page = cunt // page_limit + 1
    else:
        if cunt < page_limit:
            max_page = 1
        else:
            max_page = cunt // page_limit
    if page > max_page:
        page = max_page
    tab_list = tab.get('content')
    return render_template('purchase.html', form=pform, tabinfo=tab_list, page=[max_page + 1, page])


@pbp.route('/purchaseadd', methods=['GET', 'POST'])
@login_required
def purchaseadd():
    form_add = PurchaseAddOrderForm()
    if form_add.validate_on_submit():
        order = Purchase(pcode=form_add.code.data,
                         pdate=form_add.date.data,
                         pgoods=int(form_add.goods.data),
                         quantity=int(form_add.quantity.data),
                         univalence=float(form_add.univalence.data),
                         supplier=int(form_add.supplier.data)
                         )
        db = Dbconn()
        db.cursor.add(order)
        db.commit()
        db.close()
        return redirect('/purchase')
    return render_template('purchaseadd.html', form=form_add)


@pbp.route('/purchasedel')
@login_required
def purchasedel():
    if request.method == 'GET':
        delid = request.args.get('delid')
        db = Dbconn()
        deldata = db.cursor.query(Purchase).filter(Purchase.id == int(delid)).first()
        if deldata:
            deldata.deleted = True
        db.commit()
        db.close()
    return redirect('/purchase')


@pbp.route('/purchaseupdate', methods=['GET', 'POST'])
@login_required
def purchaseupdate():
    uform = PurchaseAddOrderForm()
    if request.method == 'GET':
        db =Dbconn()
        _order = db.cursor.query(Purchase, Goods, Supplier).join(Goods, Purchase.pgoods == Goods.id). \
            join(Supplier, Purchase.supplier == Supplier.id). \
            filter(Purchase.id==int(request.args.get('upid'))).first()
        db.close()

        uform.pid.default = _order.Purchase.id
        uform.code.default = _order.Purchase.pcode
        uform.date.default = _order.Purchase.pdate
        uform.quantity.default = _order.Purchase.quantity
        uform.univalence.default = _order.Purchase.univalence
        uform.supplier.default = _order.Purchase.supplier
        uform.goods.default = _order.Purchase.pgoods
        uform.process()
    if uform.validate_on_submit():
        _pid = uform.pid.data
        print(_pid)
        order = Purchase(pcode=uform.code.data,
                         pdate=uform.date.data,
                         pgoods=int(uform.goods.data),
                         quantity=int(uform.quantity.data),
                         univalence=float(uform.univalence.data),
                         supplier=int(uform.supplier.data)
                         )
        db = Dbconn()
        result = db.cursor.query(Purchase).filter(Purchase.id == int(_pid), Purchase.deleted==False).first()
        if result:
            result.pcode = uform.code.data
            result.pdate = uform.date.data
            result.univalence = float(uform.univalence.data)
            result.supplier = int(uform.supplier.data)
            result.pgoods = int(uform.goods.data)
            result.quantity=int(uform.quantity.data)
        db.commit()
        db.close()
        return redirect('/purchase')
    return render_template('purchaseupdate.html', form=uform)


@pbp.route('/purchasequery', methods=['GET', 'POST'])
@login_required
def purchasequery():
    cunt = 0
    page = 0
    page_limit = 10
    max_page = 0
    # num = 0
    _query_info = list()
    _orders = {}
    if request.method == 'POST':
        _sdate = request.form.get('sdate')
        _edate = request.form.get('edate')
        try:
            _pgoods = int(request.form.get('pgoods'))
        except Exception as e:
            _pgoods = ''
        try:
            _psupplier = int(request.form.get('psupplier'))
        except Exception as e:
            _psupplier = ''
    if request.method == 'GET':
        if not request.args.get('page'):
            page = 1
        else:
            page = int(request.args.get('page'))
        if page <= 0:
            page = 1
        try:
            _pgoods = int(request.args.get('goods'))
        except Exception as e:
            _pgoods = ''
        try:
            _psupplier = int(request.args.get('supplier'))
        except Exception as e:
            _psupplier = ''
        _sdate = request.args.get('sdate')
        _edate = request.args.get('edate')
    _orders = get_purchase_orders(page=page, limit=10, sdate=_sdate, edate=_edate, pgoods=_pgoods, psupllier=_psupplier)
    cunt = _orders.get('count')
    if cunt % page_limit:
        max_page = cunt // page_limit + 1
    else:
        if cunt < page_limit:
            max_page = 1
        else:
            max_page = cunt // page_limit
    if page > max_page:
        page = max_page
    _query_info.append(_pgoods)
    _query_info.append(_psupplier)
    _query_info.append(_sdate)
    _query_info.append(_edate)
    pform = PurchaseQuery()
    return render_template('purchasequery.html', form=pform, tabinfo=_orders.get('content'), page=[max_page+1, page], query_info=_query_info)
